<?php

namespace classes;

use think\facade\Cache;
use think\Db;

/*
 * redis 类库
 */

class RedisClass
{

    const PREFIX = 'vote:item_ids';
    const HASH_PREFIX = 'vote:item_id:';
    const HASH_PREFIX_OPENID = 'vote:open_id:';


    /**
     * @param $wecha_id
     */
    public static function clear_prizes_cache($wecha_id)
    {

        Cache::rm('total_count_myprizes_' . $wecha_id);

        for ($x = 1; $x <= 10; $x++) {
            Cache::rm('myprizes_' . $wecha_id . '_' . $x);
        }

    }

    /**
     * 限制单个IP访问次数
     * @param int $limit
     * @return bool
     */
    public static function getIpVisitCount($limit = 10)
    {
        $ip = request()->ip();;

        $checkCount = Cache::store('redis')->handler()->LLEN('limit:visit:ip:' . $ip);

        if ($checkCount) {
            if ($checkCount >= $limit) {
                return false;
            }
            Cache::store('redis')->handler()->LPUSH('limit:visit:ip:' . $ip, 1); //队列
            return true;

        } else {
            $limit_time = mt_rand(300, 1200);
            Cache::store('redis')->handler()->LPUSH('limit:visit:ip:' . $ip, 1); //队列
            Cache::store('redis')->handler()->expire('limit:visit:ip:' . $ip, $limit_time);//设置过期时间
            return true;
        }
    }

    /**
     * 限制单个IP投票次数
     * @param int $limit
     * @return bool
     */
    public static function getIpVoteCount($limit = 10)
    {
        $ip = request()->ip();;

        $checkCount = Cache::store('redis')->handler()->LLEN('limit:vote:ip:' . $ip);

        if ($checkCount) {
            if ($checkCount >= $limit) {
                return false;
            }
        }
        return true;
    }

    /**
     * 限制单位时间内投票次数
     * @param $key : redis key
     * @param $times : 次数
     * @param $time : key有效时间
     * @return bool
     */
    public static function getTimeVoteCount($key, $times, $time = 3600)
    {

        $value = Cache::store('redis')->get($key);
        if ($value >= $times) {
            return false;
        } elseif ($value && $value < $times) {//防刷次数
            Cache::store('redis')->inc($key);//如果有键名，添加次数
        } elseif (!$value) {
            Cache::store('redis')->set($key, 1, $time);//设置TimeOut
        }
        return true;
    }

    /**
     * 设置详情
     * @param $id
     * @param $data
     * @return bool
     */
    public static function set_redis_item($id, $data)
    {

        $HASH_PREFIX = self::HASH_PREFIX;
        if (!is_numeric($id) || !is_array($data)) return false;
        $hashName = $HASH_PREFIX . $id;
        Cache::store('redis')->handler()->hMset($hashName, $data);
//        $this->redis->zAdd($PREFIX . ':type_id:0', $id, $id);
        return true;
    }

    /**
     * 设置详情
     * @param $openid
     * @return bool
     */
    public static function set_redis_item_by_openid($openid)
    {

        $HASH_PREFIX = self::HASH_PREFIX_OPENID;
        if (empty($openid)) return false;
        $hashName = $HASH_PREFIX . $openid;

        $where['a.wechat_id'] = $openid;
        $ret = Db::name('tp_vote_item')
            ->alias('a')
            ->field('a.id,a.item,a.sub_item,a.sub_item2,a.cate_id,a.status')
            ->where($where)
            ->find();

        Cache::store('redis')->handler()->hMset($hashName, $ret);
        return true;
    }


    /**
     * 获取详情
     * @param $id
     * @return array
     */
    public static function get_redis_item_info($id)
    {

        $HASH_PREFIX = self::HASH_PREFIX;
        $ret = Cache::store('redis')->handler()->HGETALL($HASH_PREFIX . $id);
        if (!$ret) {
            $where['a.id'] = $id;
            $ret = Db::name('tp_vote_item')
                ->alias('a')
                ->join('tp_vote_cate b', 'b.cate_id=a.cate_id', 'left')
                ->join('tp_region c', 'c.id=a.province_id', 'left')
                ->join('tp_region d', 'd.id=a.city_id', 'left')
                ->field('a.id,a.item,a.sub_item,a.sub_item2,a.info,a.info2,a.address,a.type,a.cate_id,a.vcount,a.small_pic,a.startpicurl,a.startpicurl2,a.startpicurl3,a.startpicurl4,a.startpicurl5,a.ewmimage,a.videourl,a.intro,a.status,a.wechat_id,a.addtime,a.checktime,a.checkinfo,a.source,b.name cate_name,c.name province_name,d.name city_name')
                ->where($where)
                ->find();
            self::set_redis_item($id, $ret);
        }
        if ($ret) {
            $ret['vcount'] = Cache::store('redis')->handler()->zScore('vote:score:ids', $ret['id']);
        }

        if (!is_numeric($id) || (!$ret)) return [];
        return $ret;
    }

    /**
     * 获取详情(通过openid)
     * @param $openid
     * @return array
     */
    public static function get_redis_item_info_by_openid($openid)
    {

        $HASH_PREFIX = self::HASH_PREFIX_OPENID;
        $ret = Cache::store('redis')->handler()->HGETALL($HASH_PREFIX . $openid);
        if (empty($openid) || (!$ret)) return [];
        return $ret;
    }

    /**
     * 删除项目
     * @param $id
     * @return bool
     */
    public static function del_item_info($id)
    {

        $HASH_PREFIX = self::HASH_PREFIX;
        $ret = Cache::store('redis')->handler()->del($HASH_PREFIX . $id);
        return $ret;
    }

    /**
     * 删除项目
     * @param $openid
     * @return bool
     */
    public static function del_item_info_by_openid($openid)
    {

        $HASH_PREFIX = self::HASH_PREFIX_OPENID;
        $ret = Cache::store('redis')->handler()->del($HASH_PREFIX . $openid);
        return $ret;
    }

    /*
     * 获取首页分页数据
     * @param $page 当前页数
     * @param $pageSize 每页多少条
     * @param $hashName Hash 记录名称
     * @param $SortName Redis SortSet 记录名称
     * @param $redis Redis 对象
     * @param $key 字段数组 不传为取出全部字段
     * @return array
     */
    public static function get_redis_index_page_info($page, $pageSize, $type_id = 0)
    {
        if (!is_numeric($page) || !is_numeric($pageSize)) return false;
        $limit_s = ($page - 1) * $pageSize;
        $limit_e = ($limit_s + $pageSize) - 1;
        if ($type_id == 0) {
            $range = Cache::store('redis')->handler()->ZRANGE(self::PREFIX . ':type_id:0', $limit_s, $limit_e); //指定区间内，带有 score 值(可选)的有序集成员的列表。
            $count = Cache::store('redis')->handler()->zCard(self::PREFIX . ':type_id:0'); //统计ScoreSet总数
        } else {
            $range = Cache::store('redis')->handler()->ZRANGE(self::PREFIX . ':type_id:' . $type_id, $limit_s, $limit_e);
            $count = Cache::store('redis')->handler()->zCard(self::PREFIX . ':type_id:' . $type_id);
        }

        $pageCount = ceil($count / $pageSize); //总共多少页
        $pageList = array();
        foreach ($range as $qid) {
            $pageList[] = self::get_redis_item_info($qid); //获取hash表中所有的数据
        }
        $data = array(
            'data' => $pageList, //需求数据
            'page' => array(
                'page' => $page, //当前页数
                'pageSize' => $pageSize, //每页多少条
                'count' => $count, //记录总数
                'pageCount' => $pageCount //总页数
            )
        );
        return $data;
    }

    /**
     * 获取投票配置信息
     * @return mixed
     */
    public static function get_vote_config_info()
    {
        $HASH_PREFIX = 'vote:config';
        $ret = Cache::store('redis')->handler()->HGETALL($HASH_PREFIX);
        if (!$ret) {
            $data = Db::name('tp_vote')->find();
            Cache::store('redis')->handler()->hMset($HASH_PREFIX, !empty($data) ? $data : []);
            $ret = Cache::store('redis')->handler()->HGETALL($HASH_PREFIX);
        }
        return $ret;
    }

    /**
     * 获取抽奖配置信息
     * @return mixed
     */
    public static function get_lottery_config_info()
    {
        $HASH_PREFIX = 'lottery:config';
        $ret = Cache::store('redis')->handler()->HGETALL($HASH_PREFIX);
        if (!$ret) {
            $data = Db::name('tp_lottery')->find();
            Cache::store('redis')->handler()->hMset($HASH_PREFIX, !empty($data) ? $data : []);
            $ret = Cache::store('redis')->handler()->HGETALL($HASH_PREFIX);
        }
        return $ret;
    }


    /**
     * 获取banner信息
     * @return mixed
     */
    public static function get_banner_info()
    {

        $HASH_PREFIX = 'vote:banner';
        $ret = Cache::store('redis')->handler()->get($HASH_PREFIX);
        if (!$ret) {
            $list = Db::name('tp_banner')->where('is_open', 1)->order('sort desc,id desc')->select();
            $jsonBefore = json_encode($list, JSON_UNESCAPED_UNICODE);
            Cache::store('redis')->handler()->set($HASH_PREFIX, $jsonBefore);
            $ret = Cache::store('redis')->handler()->get($HASH_PREFIX);
        }
        $data = json_decode($ret, true);
        return $data;
    }


    /**
     * 设置分类详情
     * @param $id
     * @param $data
     * @return bool
     */
    public static function set_cate($id, $data)
    {

        $HASH_PREFIX = 'cate:cate_id:';
        if (!is_numeric($id) || !is_array($data)) return false;
        $hashName = $HASH_PREFIX . $id;
        Cache::store('redis')->handler()->hMset($hashName, $data);
        return true;
    }

    /**
     * 获取分类详情
     * @param $id
     * @return bool
     */
    public static function get_cate_info($id)
    {

        $HASH_PREFIX = 'cate:cate_id:';
        $ret = Cache::store('redis')->handler()->HGETALL($HASH_PREFIX . $id);
        if (!$ret) {
            $where['cate_id'] = $id;
            $ret = Db::name('tp_vote_cate')
                ->where($where)
                ->where('pid', 0)
                ->find();
            self::set_redis_item($id, $ret);
        }

        if (!is_numeric($id) || (!$ret)) return false;
        return $ret;
    }


    /**
     * 获取全部分类
     * @return mixed
     */
    public static function get_cate_list()
    {

        $HASH_PREFIX = 'new_cate:list';
        $ret = Cache::store('redis')->handler()->get($HASH_PREFIX);
        if (!$ret) {
            $list = Db::name('tp_vote_cate')->where('pid', 0)->order('sort desc,cate_id desc')->select();
            $jsonBefore = json_encode($list, JSON_UNESCAPED_UNICODE);
            Cache::store('redis')->handler()->set($HASH_PREFIX, $jsonBefore);
            $ret = Cache::store('redis')->handler()->get($HASH_PREFIX);
        }
        $data = json_decode($ret, true);
        return $data;
    }

    /*
     * 清空数据
     * @param string $type db:清空当前数据库 all:清空所有数据库
     * @return bool
     */
    public static function clear($type = 'db')
    {
        if ($type == 'db') {
            Cache::store('redis')->handler()->flushDB();
        } elseif ($type == 'all') {
            Cache::store('redis')->handler()->flushAll();
        } else {
            return false;
        }
        return true;
    }

}